package com.huanghuai.retail.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huanghuai.retail.common.R;
import com.huanghuai.retail.dto.InformationDto;
import com.huanghuai.retail.entity.PBrandType;
import com.huanghuai.retail.entity.PInformation;
import com.huanghuai.retail.entity.PType;
import com.huanghuai.retail.service.BrandService;
import com.huanghuai.retail.service.BrandTypeService;
import com.huanghuai.retail.service.InformationService;
import com.huanghuai.retail.service.TypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/information")
public class InformationController {

    @Autowired
    private InformationService informationService;

    @Autowired
    private TypeService typeService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private BrandTypeService brandTypeService;

    /**
     * 根据id查询一条商品信息，并封装到dto中, 这个操作主要用于修改时显示信息
     * @param id
     * @return
     */
    @GetMapping("find/{id}")
    public R<InformationDto> findById(@PathVariable Long id){
        PInformation information = informationService.getById(id);
        if (information == null)
            return R.error("查询数据失败");

        InformationDto informationDto = informationService.disposeDto(information);

        return R.success(informationDto);
    }

    /**
     * 查询操作
     * 根据条件查询商品并进行分页查询
     *
     *  问题：有一组type或brand的ids如何进行查询对应信息
     *  解决：使用lambdaQueryWrapper.in 传入参数与eq一样，只是最后一个参数变成了数组
     *
     *     注意：in操作中数组不能为空，我传了以后-1，使他不为空
     * @param page
     * @param pageSize
     * @param name
     * @param type
     * @param brand
     * @param warp
     * @return
     */
    @GetMapping("page")
    public R<Page> findByCondition(@RequestParam(defaultValue = "1")int page,
                                   @RequestParam(defaultValue = "10")int pageSize,
                                   String name, String type, String brand, String warp){

        //分页构造器
        Page<PInformation> pageInfo = new Page<>(page, pageSize);

        LambdaQueryWrapper<PInformation> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        //处理warp，直接模糊查询
        lambdaQueryWrapper.like(warp!=null, PInformation::getWrap, warp);

        //处理name，直接模糊查询
        lambdaQueryWrapper.like(name!=null, PInformation::getName, name);

        //处理type，先模糊查询获取type的id，再进行in查询
        List<Long> typeIds = null;
        if (type != null)
            typeIds = typeService.getIdsByName(type);
        if (typeIds != null && typeIds.size() == 0)
            typeIds.add(-1L);
        lambdaQueryWrapper.in(typeIds!=null, PInformation::getTypeId, typeIds);

        //处理brand，先模糊查询获取brand的id，再进行in查询
        List<Long> brandIds = null;
        if (brand != null)
            brandIds = brandService.getIdsByName(brand);
        if (brandIds != null && brandIds.size() == 0)
            brandIds.add(-1L);
        lambdaQueryWrapper.in(brandIds!=null,PInformation::getBrandId, brandIds);

        //执行分页查询
        informationService.page(pageInfo,lambdaQueryWrapper);

        //查询商品信息
        List<PInformation> list = pageInfo.getRecords();
        if (list.size() == 0)
            return R.error("未查询到信息");

        //封装成dto信息到Page中
        List<InformationDto> listDto = new ArrayList<>();
        Page<InformationDto> informationDtoPage = new Page<>();
        BeanUtils.copyProperties(pageInfo, informationDtoPage, "records");
        for (int i = 0; i < list.size(); i ++)
            listDto.add(informationService.disposeDto(list.get(i)));
        informationDtoPage.setRecords(listDto);

        return R.success(informationDtoPage);
    }


    /**
     * 新增时时间出了问题，这个问题在火车票里出现过，但不知道为啥当时解决了。
     *  已经解决， 实体类数据类型应该为LocalDateTime
     *
     *  疑问：前端新增时对于工厂、品牌信息肯定是传入查到的具体名称，而非id，应该怎么解决。
     *      前端解决
     *
     *  问题： 1、图片的上传和下载问题
     *          解决：编写了controller类写了下载与展示图片的方法，下载时返回路径名称，存入数据库，
     *              上传时，根据路径名称将图片展示到前端
     * @param information
     * @return
     */
    @PostMapping("add")
    public R<String> addInformation(@RequestBody PInformation information){

        if (!informationService.pdInformation(information))
            return R.error("传入信息不全或错误");
        //保存商品
        informationService.save(information);
        //维护品牌类别表
        informationService.maintenance(information);
        return R.success("保存成功");
    }

    /**
     * 修改操作，有一些问题，因为前端展示的其实是Dto，那么修改的是Dto中特有的信息而非实体类中的信息
     *  那么穿过来的数据虽然可以用实体类接收，但是修改Dto特有信息应该怎么对应到实体类中的信息呢？
     *      疑问：是前端页面做了绑定？(修改Dto中特有数据时，同时修改传回来实体类对应的信息)
     *           后端接收Dto数据，再根据Dto中特有数据进行查询塞入实体类中进行修改？
     *     前端解决
     *
     *  问题：1、对于brandType的中间表维护，不应该先删除再新增
     * @param information
     * @return
     */
    @PutMapping("update")
    public R<String> updateInformation(@RequestBody PInformation information){

        if (informationService.pdInformation(information))
            return R.error("修改失败");
        //判断是否删除之前已有中间表信息
        informationService.pdDelBrandType(information);

        //修改并维护商品类别信息
        informationService.maintenance(information);

        informationService.updateById(information);
        return R.success("修改成功");
    }
}
